package com.sprouting.personal.controller;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.*;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Dict;
import com.sprouting.personal.model.entity.Homework;
import com.sprouting.personal.model.entity.HomeworkRecord;
import com.sprouting.personal.model.vo.HomeworkSubmitStatistics;
import com.sprouting.personal.model.vo.HomeworkTask;
import com.sprouting.personal.model.vo.HomeworkVo;
import com.sprouting.personal.model.vo.MemberFamilyVo;
import com.sprouting.personal.service.DictService;
import com.sprouting.personal.service.HomeworkRecordService;
import com.sprouting.personal.service.HomeworkService;
import com.sprouting.personal.service.MemberFamilyService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import com.sprouting.personal.utils.NetTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 家庭作业 控制层
 *
 * @author ：sprouting
 * @date 创建时间： 2023-07-15 10:36:31
 */
@Slf4j
@RestController
@RequestMapping("homework")
public class HomeworkController {

	@Autowired
	private HomeworkService homeworkService;
	@Autowired
	private DictService dictService;
	@Autowired
	private HomeworkRecordService homeworkRecordService;
	@Autowired
	private MemberFamilyService memberFamilyService;

	@Value("${server.port}")
	private String port;
	/**
	 * token名称，防止token取其他的名字
	 */
	@Value("${sa-token.token-name:token}")
	private String tokenName;


	/**
	 * 线程安全的map，只适用于单机系统，这样也不用去考虑资源释放问题，多机版本的则不在这里使用
	 */
	private final static ConcurrentHashMap<String, String> CONCURRENT_HASH_MAP = new ConcurrentHashMap<>();




	/**
	 * 获取大屏二维码
	 * @param dev 开发还是生产 dev 开发
	 * @return
	 */
	@PostMapping("/getLargeScreenQrCode")
	public ResultJson getLargeScreenQrCode(String dev) {
		if (CheckTool.checkNull(dev)){
			dev = "dev";
		}

		String ip = NetTool.getLocalHostLANAddress();
		String server;
		if ("dev".equals(dev)){
			// 开发，如果还不能访问，需要考虑是否前端 设置的是 localhost，要修改为 0.0.0.0 或者 当前IP否则无法远程访问，如果发现访问进入页面但是报错，那则是前端没有设置正确IP的问题
			server = String.format("http://%s:8083/#/toHomeworkView?%s=%s", ip, tokenName, StpUtil.getTokenValue());

		} else {
			// 生产
			server = String.format("http://%s:%s/index.html#/toHomeworkView?%s=%s", ip, port, tokenName, StpUtil.getTokenValue());
		}

		log.info(server);
		// 二维码
		QrConfig config = new QrConfig(250, 250);
		// 设置边距，既二维码和背景之间的边距
		config.setMargin(3);
		String base64 = QrCodeUtil.generateAsBase64(server, config, ImgUtil.IMAGE_TYPE_PNG);
		return ResultJson.success(base64);
	}


	/**
	 * 获取过去5天的作业提交数量
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("getHomeworkSubmitStatisticsDay")
	public ResultJson getHomeworkSubmitStatisticsDay(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		List<HomeworkSubmitStatistics> homeworkSubmitStatisticsList = homeworkRecordService.getHomeworkSubmitStatisticsDay(memberFamilyId);
		if (CollUtil.isEmpty(homeworkSubmitStatisticsList)){
			homeworkSubmitStatisticsList = new ArrayList<>();
		}
		Map<String, HomeworkSubmitStatistics> map = homeworkSubmitStatisticsList.stream().collect(Collectors.toMap(HomeworkSubmitStatistics::getDay, Function.identity()));

		// 获取5天
		DateTime offset = DateUtil.offsetDay(new Date(), -4);
		List<DateTime> list = DateUtil.rangeToList(offset, new Date(), DateField.DAY_OF_YEAR);
		// 补全数据
		for (DateTime dateTime : list) {
			String date = DateUtil.format(dateTime, DatePattern.NORM_DATE_PATTERN);
			HomeworkSubmitStatistics homeworkSubmitStatistics = map.get(date);
			if (homeworkSubmitStatistics == null){
				homeworkSubmitStatistics = new HomeworkSubmitStatistics();
				homeworkSubmitStatistics.setSubmitNum(0L);
				homeworkSubmitStatistics.setDay(date);
				homeworkSubmitStatisticsList.add(homeworkSubmitStatistics);
			}
		}

		// 排序
		List<HomeworkSubmitStatistics> sortedList = homeworkSubmitStatisticsList.stream().sorted(Comparator.comparing(HomeworkSubmitStatistics::getDay)).collect(Collectors.toList());
		return ResultJson.success(sortedList);
	}


	/**
	 * 获取作业提交统计,按月
	 * 这里获取最近5个月的作业提交情况
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("getHomeworkSubmitStatisticsMonth")
	public ResultJson getHomeworkSubmitStatisticsMonth(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		List<HomeworkSubmitStatistics> homeworkSubmitStatisticsList = homeworkRecordService.getHomeworkSubmitStatisticsMonth(memberFamilyId);
		if (CollUtil.isEmpty(homeworkSubmitStatisticsList)){
			homeworkSubmitStatisticsList = new ArrayList<>();
		}
		Map<String, HomeworkSubmitStatistics> map = homeworkSubmitStatisticsList.stream().collect(Collectors.toMap(HomeworkSubmitStatistics::getMonth, Function.identity()));

		// 获取5个月前的时间
		DateTime offset = DateUtil.offset(new Date(), DateField.MONTH, -4);
		List<DateTime> list = DateUtil.rangeToList(offset, new Date(), DateField.MONTH);
		// 补全数据
		for (DateTime dateTime : list) {
			String date = DateUtil.format(dateTime, "yyyy-MM");
			HomeworkSubmitStatistics homeworkSubmitStatistics = map.get(date);
			if (homeworkSubmitStatistics == null){
				homeworkSubmitStatistics = new HomeworkSubmitStatistics();
				homeworkSubmitStatistics.setSubmitNum(0L);
				homeworkSubmitStatistics.setMonth(date);
				homeworkSubmitStatisticsList.add(homeworkSubmitStatistics);
			}
		}

		// 排序
		List<HomeworkSubmitStatistics> sortedList = homeworkSubmitStatisticsList.stream().sorted(Comparator.comparing(HomeworkSubmitStatistics::getMonth)).collect(Collectors.toList());
		return ResultJson.success(sortedList);
	}

	/**
	 * 获取作业提交统计,按年
	 * 这里获取最近5年的作业提交情况
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("getHomeworkSubmitStatisticsYear")
	public ResultJson getHomeworkSubmitStatisticsYear(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		List<HomeworkSubmitStatistics> homeworkSubmitStatisticsList = homeworkRecordService.getHomeworkSubmitStatisticsYear(memberFamilyId);
		if (CollUtil.isEmpty(homeworkSubmitStatisticsList)){
			homeworkSubmitStatisticsList = new ArrayList<>();
		}
		Map<String, HomeworkSubmitStatistics> map = homeworkSubmitStatisticsList.stream().collect(Collectors.toMap(HomeworkSubmitStatistics::getYear, Function.identity()));

		// 获取5年前的时间
		DateTime offset = DateUtil.offset(new Date(), DateField.YEAR, -4);
		List<DateTime> list = DateUtil.rangeToList(offset, new Date(), DateField.YEAR);
		// 补全数据
		for (DateTime dateTime : list) {
			String date = DateUtil.format(dateTime, "yyyy");
			HomeworkSubmitStatistics homeworkSubmitStatistics = map.get(date);
			if (homeworkSubmitStatistics == null){
				homeworkSubmitStatistics = new HomeworkSubmitStatistics();
				homeworkSubmitStatistics.setSubmitNum(0L);
				homeworkSubmitStatistics.setYear(date);
				homeworkSubmitStatisticsList.add(homeworkSubmitStatistics);
			}
		}

		// 排序
		List<HomeworkSubmitStatistics> sortedList = homeworkSubmitStatisticsList.stream().sorted(Comparator.comparing(HomeworkSubmitStatistics::getYear)).collect(Collectors.toList());
		return ResultJson.success(sortedList);
	}


	/**
	 * 根据家庭成员ID 获取完成次数做多的作业10条
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("getCompleteTheMostTask")
	public ResultJson getCompleteTheMostTask(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		return ResultJson.success(homeworkService.getCompleteTheMostTask(memberFamilyId));
	}

	/**
	 * 根据家庭成员ID获取最近执行的100条家庭作业记录
	 * @param memberFamilyId 家庭成员id
	 * @return
	 */
	@PostMapping("getLast100Log")
	public ResultJson getLast100Log(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		return ResultJson.success(homeworkService.getLast100Log(memberFamilyId));
	}

	/**
	 * 获取学科作业数量和名称
	 * @param memberFamilyId 家庭成员id
	 * @return
	 */
	@PostMapping("getDisciplinesNameNum")
	public ResultJson getDisciplinesNameNum(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		return ResultJson.success(homeworkService.getDisciplinesNameNum(memberFamilyId));
	}

	/**
	 * 统计作业数据
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("/statistics")
	public ResultJson statistics(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		return ResultJson.success(homeworkService.statistics(memberFamilyId));
	}

	/**
	 * 修改检查状态
	 * @param homeworkId 作业ID
	 * @param checkHomework 可修改的状态
	 * @return
	 */
	@PostMapping("/updCheck")
	public ResultJson updCheck(String homeworkId, Integer checkHomework){
		if (CheckTool.checkNull(homeworkId)){
			return ResultJson.errorIllegal();
		}
		if (checkHomework == null){
			return ResultJson.errorIllegal();
		}

		Homework homework = homeworkService.getHomeworkById(homeworkId);
		homework.setCheckHomework(checkHomework);
		EntityTool.buildUpdBase(homework, StpUtil.getLoginIdAsString());
		homeworkService.updateById(homework);
		return ResultJson.success();
	}

	/**
	 * 获取子女信息
	 * @return
	 */
	@PostMapping("/getSonInfo")
	public ResultJson getSonInfo(){
		return ResultJson.success(memberFamilyService.getSonInfo(StpUtil.getLoginIdAsString()));
	}

	/**
	 * 查询作业日志
	 * @param page 分页参数
	 * @param homeworkRecord 查询参数
	 * @return
	 */
	@PostMapping("/getHomeworkRecord")
	public ResultJson getHomeworkRecord(Page page, HomeworkRecord homeworkRecord){
		if (homeworkRecord == null){
			homeworkRecord = new HomeworkRecord();
		}
		if (CheckTool.checkNull(homeworkRecord.getHomeworkId())){
			return ResultJson.errorIllegal();
		}

		homeworkRecord.setUserId(StpUtil.getLoginIdAsString());
		return ResultJson.success(homeworkRecordService.getHomeworkRecordPage(page, homeworkRecord));
	}

	/**
	 * 获取未检查的作业
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("/getUncheckedHomework")
	public ResultJson getUncheckedHomework(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		return ResultJson.success(homeworkService.getUncheckedHomework(memberFamilyId));
	}

	/**
	 * 获取今天已完成的作业
	 * 只要记录表有记录，则今天完成过，而不是查询状态
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("/getHomeworkCompletedToday")
	public ResultJson getHomeworkCompletedToday(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		List<HomeworkVo> homeworkVoList = homeworkService.getHomeworkCompletedToday(memberFamilyId, new Date());
		return ResultJson.success(homeworkVoList);
	}

	/**
	 * 获取指定家庭成员今天待做的作业和已逾期的作业
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	@PostMapping("/getTask")
	public ResultJson getTask(String memberFamilyId){
		if (CheckTool.checkNull(memberFamilyId)){
			return ResultJson.errorIllegal();
		}

		HomeworkTask homeworkTask = tryGetHomeworkTask(memberFamilyId, 1);
		// 找到今日完成的，周期性的不会继续已经查询出来了，只要查询非周期性的
		List<HomeworkVo> completedTodayList = homeworkRecordService.getHomeworkRecordByCreateTime(memberFamilyId);
		homeworkTask.getCompletedTodayList().addAll(completedTodayList);
		return ResultJson.success(homeworkTask);
	}

	/**
	 * 刷新家庭作业
	 * 单纯的刷新，不做获取.这里等于当定时任务用
	 * @return
	 */
	@GetMapping("refreshHomework")
	public ResultJson refreshHomework(){
		List<MemberFamilyVo> sonList = memberFamilyService.getSonInfo(StpUtil.getLoginIdAsString());
		if (CollUtil.isEmpty(sonList)){
			return ResultJson.success();
		}

		for (MemberFamilyVo memberFamilyVo : sonList) {
			getMemberFamilyIdTaskLock(memberFamilyVo.getId());
		}

		return ResultJson.success();
	}

	/**
	 * 作业签收,自动判断是否延期
	 * @param homeworkId 作业ID
	 * @return
	 */
	@PostMapping("/homeworkCompletedNormal")
	public ResultJson homeworkCompletedNormal(String homeworkId){
		if (CheckTool.checkNull(homeworkId)){
			return ResultJson.errorIllegal();
		}

		Homework homework = homeworkService.getHomeworkById(homeworkId);
		HomeworkTask homeworkTask = tryGetHomeworkTask(homework.getMemberFamilyId(), 1);

		List<HomeworkVo> todayList = homeworkTask.getTodayList();
		Map<String, HomeworkVo> todayMap = todayList.stream().collect(Collectors.toMap(HomeworkVo::getId, Function.identity()));

		List<HomeworkVo> arrearsWithList = homeworkTask.getArrearsWithList();
		Map<String, HomeworkVo> arrearsWithMap = arrearsWithList.stream().collect(Collectors.toMap(HomeworkVo::getId, Function.identity()));

		HomeworkVo todayHomeworkVo = todayMap.get(homeworkId);
		HomeworkRecord homeworkRecord;
		// 本次执行的时间
		Date thisExecTime;

		if (todayHomeworkVo != null){
			// 今天的
			homeworkRecord = buildHomeworkRecord(todayHomeworkVo);
			// 经过上面的方法，已经有了要执行的时间
			thisExecTime = todayHomeworkVo.getThisExecTime();

		} else {
			// 逾期
			HomeworkVo arrearsWithHomeworkVo = arrearsWithMap.get(homeworkId);
			if (arrearsWithHomeworkVo != null){
				homeworkRecord = buildHomeworkRecord(arrearsWithHomeworkVo);
				thisExecTime = arrearsWithHomeworkVo.getThisExecTime();

			} else {
				return ResultJson.error("当前作业不需要提交");
			}
		}

		// 更新时间即可
		if (thisExecTime != null){
			if (DateUtil.between(DateUtil.beginOfDay(new Date()), DateUtil.beginOfDay(thisExecTime), DateUnit.DAY, false) > 0){
				return ResultJson.error("今日作业已完成，不需要重复完成");
			}
			// 只更新时间
			homework.setExecTime(thisExecTime);
			if (!Constant.HomeworkCheck.PERMANENT.equals(homework.getCheckHomework())){
				// 非永久不检查的，变更为检查
				homework.setCheckHomework(Constant.HomeworkCheck.NO);
			}
			homeworkService.homeworkCompletedNormal(thisExecTime, homeworkId, homework.getCheckHomework(), homeworkRecord);

		} else {
			// 不需要执行
		}

		return ResultJson.success();
	}

	/**
	 * 分页查询家庭作业
	 * @param page 分页参数
	 * @param homework 查询参数
	 * @return
	 */
	@PostMapping("/getHomeworkListPage")
	public ResultJson getHomeworkListPage(Page page, Homework homework){
		if (homework == null){
			homework = new Homework();
		}
		homework.setUserId(StpUtil.getLoginIdAsString());

		return ResultJson.success(homeworkService.getHomeworkPage(page, homework));
	}

	/**
	 * 获取家庭作业类型
	 * @return
	 */
	@PostMapping("/getHomeworkType")
	public ResultJson<List<Dict>> getHomeworkType(){
		List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.HOMEWORK_GROUP, StpUtil.getLoginIdAsString());
		return ResultJson.success(dictList);
	}

	/**
	 * 保存家庭作业
	 * @param homework 家庭作业
	 * @return
	 */
	@ApiIdempotent
	@PostMapping("saveHomework")
	public ResultJson saveHomework(@Validated(AddGroup.class) Homework homework){
		String msg = checkHomework(homework);
		if (msg != null){
			return ResultJson.error(msg);
		}

		homework.setId(IdTool.getId());
		homework.setUserId(StpUtil.getLoginIdAsString());
		EntityTool.buildSaveBase(homework, StpUtil.getLoginIdAsString());
		// 已开始的不能进行处理
		homework.setStatus(Constant.HomeworkStatus.WAIT);
		homeworkService.save(homework);
		return ResultJson.success(homework);
	}

	/**
	 * 更新家庭作业
	 * @param homework 家庭作业
	 * @return
	 */
	@ApiIdempotent
	@PostMapping("updHomework")
	public ResultJson updHomework(@Validated(UpdGroup.class) Homework homework){
		String msg = checkHomework(homework);
		if (msg != null){
			return ResultJson.error(msg);
		}

		// 有一些参数不能更新，否则会导致逻辑问题
		homework.setType(null);
		homework.setStartTime(null);
		homework.setExecTime(null);
		homework.setFrequency(null);

		EntityTool.buildUpdBase(homework, StpUtil.getLoginIdAsString());
		homeworkService.updateById(homework);
		return ResultJson.success(homework);
	}

	/**
	 * 物理删除家庭作业
	 * @param id 家庭作业ID
	 * @return
	 */
	@ApiIdempotent
	@PostMapping("/delHomeworkById")
	public ResultJson delHomeworkById(String id){
		if (CheckTool.checkNull(id)){
			return ResultJson.errorIllegal();
		}

		homeworkService.delHomeworkById(id);
		return ResultJson.success(null);
	}

	/**
	 * 获取任务，因为这个必须获取，所以进行三次尝试，三次没获取到则强行获取
	 * @param memberFamilyId 家庭成员ID
	 * @param lockNum 当前第几个加锁
	 * @return
	 */
	private HomeworkTask tryGetHomeworkTask(String memberFamilyId, int lockNum){
		if (lockNum > 3){
			// 强制获取
			return getMemberFamilyIdTask(memberFamilyId);

		} else {
			// 这里的获取作业如果多个一起操作的时候可能会有锁冲突问题
			String key = CONCURRENT_HASH_MAP.get(memberFamilyId);
			if (key != null){
				log.warn("{}存在锁定任务，等待几秒后执行", lockNum);
				ThreadUtil.sleep(2000);
				return tryGetHomeworkTask(memberFamilyId, lockNum + 1);

			} else {
				return getMemberFamilyIdTask(memberFamilyId);
			}
		}
	}

	/**
	 * 检查家庭作业并补充数据
	 * @param homework 家庭作业
	 * @return 非null则无异常
	 */
	private String checkHomework(Homework homework){
		if (Constant.HomeworkStatus.WAIT.equals(homework.getStatus()) || homework.getStatus() == null){

		} else {
			return "进行中的作业不能进行操作";
		}

		if (homework.getOptional() == null){
			homework.setOptional(Constant.YesOrNo.YES);
		}
		if (homework.getAdditional() == null){
			homework.setAdditional(Constant.YesOrNo.YES);
		}
		if (homework.getDifficulty() == null){
			homework.setDifficulty(1);
		}
		if (homework.getCheckHomework() == null){
			homework.setCheckHomework(Constant.HomeworkCheck.NO);
		}

		if (homework.getFrequency() <= 0){
			return "非法的执行频率";
		}
		if (DateUtil.between(new Date(), homework.getStartTime(), DateUnit.DAY, false) < 0){
			// 负数为之前的 homework.getStartTime() 小于 当前时间
			return "作业开始时间不能小于当前时间";
		}

		if (Constant.HomeworkType.SAME_DAY.equals(homework.getType())){
			// 当天完成，则结束时间也是当天
			homework.setDeadline(homework.getStartTime());
			homework.setFrequency(1);

		} else if (Constant.HomeworkType.CYCLE.equals(homework.getType())){
			if (homework.getFrequency() == null){
				return "请选择执行频率";
			}
			if (homework.getDeadline() == null){
				// 截止时间为空的情况下
				homework.setDeadline(DateUtil.parse("2099-01-01 01:01:01"));
			}

		} else if (Constant.HomeworkType.LIMITED_TIME.equals(homework.getType())){
			if (homework.getDeadline() == null){
				return "作业截止时间不能为空";
			}
			homework.setFrequency(1);

		} else {
			return "无法识别的作业类型";
		}

		if (homework.getDeadline().getTime() < homework.getStartTime().getTime()){
			return "作业开始时间不能小于截止时间";
		}

		return null;
	}

	/**
	 * 构建家庭作业记录表
	 * @param homework 家庭作业
	 * @return
	 */
	private HomeworkRecord buildHomeworkRecord(HomeworkVo homework){
		HomeworkRecord homeworkRecord = new HomeworkRecord();
		homeworkRecord.setId(IdTool.getId());
		homeworkRecord.setUserId(homework.getUserId());
		homeworkRecord.setMemberFamilyId(homework.getMemberFamilyId());
		homeworkRecord.setHomeworkId(homework.getId());
		homeworkRecord.setSubmitTime(homework.getThisExecTime());
		EntityTool.buildSaveBase(homeworkRecord, StpUtil.getLoginIdAsString());
		if (Constant.HomeworkStatus.DELAY.equals(homework.getStatus())){
			// 逾期的
			homeworkRecord.setSupplementary(Constant.YesOrNo.YES);
		} else {
			homeworkRecord.setSupplementary(Constant.YesOrNo.NO);
		}
		return homeworkRecord;
	}


	/**
	 * 获取指定家庭成员的作业情况 - 先期的加锁处理
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	private HomeworkTask getMemberFamilyIdTaskLock(String memberFamilyId){
		String value = CONCURRENT_HASH_MAP.putIfAbsent(memberFamilyId, "1");
		if (StrUtil.isNotBlank(value)){
			log.info("{} 家庭成员作业状态正在修正中", memberFamilyId);
			return new HomeworkTask();
		}

		try {
			return getMemberFamilyIdTask(memberFamilyId);
		} finally {
			// 释放锁
			CONCURRENT_HASH_MAP.remove(memberFamilyId);
		}
	}

	/**
	 * 获取指定家庭成员的作业情况
	 * 修正现在的状态，并获取到下次的执行时间
	 * @param memberFamilyId 家庭成员ID
	 * @return
	 */
	private HomeworkTask getMemberFamilyIdTask(String memberFamilyId){
		HomeworkTask homeworkTask = new HomeworkTask();

		// 查询出未完成的
		List<HomeworkVo> list = homeworkService.getIncompleteHomeworkByMemberFamilyId(memberFamilyId);
		if (CollUtil.isEmpty(list)){
			return homeworkTask;
		}

		// 非空开始循环
		for (HomeworkVo homeworkVo : list){
			if (homeworkVo.getStartTime().getTime() >= System.currentTimeMillis()){
				// 作业还未开始
				continue;
			}

			// 都是已经开始需要执行的作业
			if (Constant.HomeworkType.SAME_DAY.equals(homeworkVo.getType())){
				/// 当天必须完成，只执行一次的
				if (homeworkVo.getExecTime() == null){
					// 从来没有执行过
					// 开始的时间和今天的时间是否相差
					long time = DateUtil.betweenDay(homeworkVo.getStartTime(), new Date(), true);
					if (time == 0){
						// 今天的作业
						homeworkVo.setStatus(Constant.HomeworkStatus.RUN);
						homeworkTask.getTodayList().add(homeworkVo);
					} else {
						// 拖欠的作业
						homeworkVo.setDaysInArrears(time);
						homeworkVo.setStatus(Constant.HomeworkStatus.DELAY);
						homeworkTask.getArrearsWithList().add(homeworkVo);
					}

					// 未执行过，则执行时间就是开始时间
					homeworkVo.setThisExecTime(homeworkVo.getStartTime());
					EntityTool.buildUpdBase(homeworkVo, StpUtil.getLoginIdAsString());
					homeworkService.updateById(homeworkVo);
					continue;

				} else {
					// 前面已经验证了开始时间，并且已经执行过，这种数据是异常数据，直接修正即可
					homeworkVo.setStatus(Constant.HomeworkStatus.COMPLETE);
					EntityTool.buildUpdBase(homeworkVo, StpUtil.getLoginIdAsString());
					homeworkService.updateById(homeworkVo);
				}


			} else if (Constant.HomeworkType.CYCLE.equals(homeworkVo.getType())){
                /*
				场景说明：
				 比如，假设现在是10月1日，我定义了一个任务10月10日开始执行，10月20日结束，在中间这个时间，每2天执行一次，因为现在是10月1日，那现在这个任务不要执行，假如到了10月10日
				 ，则当天需要执行这个任务，如果10号执行了执行了，则11号不需要执行，12号需要执行，如果12号忘记执行了，则13号照样提示要执行。如果已经超过20号了，则要检查20号之前是否
				 都执行完了，正确的话应该执行了5次，如果结束时间时间已经到了，但还没执行，照样可以执行，每天都行，但如果已经有足够的执行次数则不需要继续执行了
				 */

				// 总的相隔天数，开始到结束的总天数
				long sumExec = DateUtil.betweenDay(DateUtil.beginOfDay(homeworkVo.getStartTime()), DateUtil.beginOfDay(homeworkVo.getDeadline()), true);
				// 开始到今天的间隔时间，开始到今天的总天数
				long todayExec = DateUtil.betweenDay(DateUtil.beginOfDay(homeworkVo.getStartTime()), DateUtil.beginOfDay(new Date()), true);
				// 总的应该执行次数
				long sumFre = 1;
				// 到今天应该执行的次数
				long dayFre = 0;
				if (sumExec > homeworkVo.getFrequency()){
					sumFre = sumExec / homeworkVo.getFrequency();
				}
				// if (todayExec > homeworkVo.getFrequency()){
					dayFre = todayExec / homeworkVo.getFrequency();
				// }

				if (homeworkVo.getExecTime() == null){
					// 还从来没执行过,直接是开始时间为第一次的执行时间。不应该给值，给了就是已经执行过了
					// 判断是否逾期,直接判断今天应该执行的次数，因为未执行过又到了执行时间，所以第一天的执行必然是第一次，相等则未逾期。
					// 上面的判断应该错了，直接判断今天是否超过开始时间即可，两者为0则就是今天的，否则已逾期
					if (0 == todayExec){
						homeworkVo.setStatus(Constant.HomeworkStatus.RUN);
						homeworkTask.getTodayList().add(homeworkVo);

					} else {
						// 已逾期
						homeworkVo.setStatus(Constant.HomeworkStatus.DELAY);
						homeworkTask.getArrearsWithList().add(homeworkVo);
					}

					homeworkVo.setDaysInArrears(DateUtil.betweenDay(homeworkVo.getStartTime(), new Date(), true));
					// 因为没有执行开始时间，使用开始时间计算
					homeworkVo.setDaysToEnd(DateUtil.betweenDay(homeworkVo.getStartTime(), homeworkVo.getDeadline(), true));
					// 一次都没执行
					homeworkVo.setCompleteNum(0L);
					// 没执行过一次，则开始时间就是第一次执行的时间
					homeworkVo.setThisExecTime(homeworkVo.getStartTime());

				} else {
					// 已经执行过了,则执行时间 + 新的周期，是否超过当前时间，计算出下一次的执行时间
					// 在已执行的基础上，计算出下一次的执行时间
					DateTime netTime = DateUtil.offsetDay(homeworkVo.getExecTime(), homeworkVo.getFrequency());
					// 下一次的执行时间到开始的间隔
					long netExec = DateUtil.betweenDay(DateUtil.beginOfDay(homeworkVo.getStartTime()), DateUtil.beginOfDay(netTime), true);
					// 下一次到开始应该执行的次数
					long nexFre = 1;
					if (netExec >= homeworkVo.getFrequency()){
						nexFre = netExec / homeworkVo.getFrequency();
						// 少了开始的那一天，否则2天一次，从1号开始，现在2号，2天了，实际第一天就是开始时间
						// nexFre ++;
					}

					if (nexFre > sumFre){
						// 属于已经完成的，因为上次执行已经是最后一次执行了
						homeworkVo.setStatus(Constant.HomeworkStatus.COMPLETE);
						EntityTool.buildUpdBase(homeworkVo, StpUtil.getLoginIdAsString());
						homeworkService.updateById(homeworkVo);
						continue;
					}

					// 未超过最大次数，则还在范围内，可能完成或未完成
					if (nexFre > dayFre){
						// 超过今天，则已经执行过了。
						homeworkVo.setStatus(Constant.HomeworkStatus.RUN);
						// 下一次的执行不需要进行，还是原来的
						// homeworkTask.getCompletedTodayList().add(homeworkVo);

					} else if (nexFre == dayFre){
						// 今天的周期和下一次的周期一样，则是未过期的
						// homeworkVo.setExecTime(netTime);
						homeworkVo.setStatus(Constant.HomeworkStatus.RUN);
						homeworkTask.getTodayList().add(homeworkVo);
						homeworkVo.setThisExecTime(netTime);

					} else {
						// 属于逾期的
						// homeworkVo.setExecTime(netTime);
						homeworkVo.setStatus(Constant.HomeworkStatus.DELAY);
						homeworkTask.getArrearsWithList().add(homeworkVo);
						homeworkVo.setThisExecTime(netTime);
					}

					homeworkVo.setDaysInArrears(DateUtil.betweenDay(homeworkVo.getExecTime(), new Date(), true));
					homeworkVo.setDaysToEnd(DateUtil.betweenDay(homeworkVo.getExecTime(), homeworkVo.getDeadline(), true));
					// homeworkVo.setCompleteNum(nexFre - 1);
					homeworkVo.setCompleteNum(nexFre);
				}

				EntityTool.buildUpdBase(homeworkVo, StpUtil.getLoginIdAsString());
				homeworkService.updateById(homeworkVo);
				continue;


			} else if (Constant.HomeworkType.LIMITED_TIME.equals(homeworkVo.getType())){
				/// 在规定时间完成即可
				if (homeworkVo.getExecTime() != null){
					// 异常数据，修正即可
					homeworkVo.setStatus(Constant.HomeworkStatus.COMPLETE);
					EntityTool.buildUpdBase(homeworkVo, StpUtil.getLoginIdAsString());
					homeworkService.updateById(homeworkVo);
					continue;
				}

				// 未执行的,检查是否超过最终的时间，超过则是已逾期
				if (homeworkVo.getDeadline().getTime() < System.currentTimeMillis()){
					// 已逾期
					homeworkVo.setDaysInArrears(DateUtil.betweenDay(homeworkVo.getDeadline(), new Date(), true));
					homeworkVo.setStatus(Constant.HomeworkStatus.DELAY);
					homeworkTask.getArrearsWithList().add(homeworkVo);
					// 理论上，执行时间应该为今天，但这里之前做了定义，只能选择范围内的时间
					homeworkVo.setThisExecTime(homeworkVo.getDeadline());

				} else {
					// 未逾期
					homeworkVo.setDaysToEnd(DateUtil.betweenDay(homeworkVo.getDeadline(), new Date(), true));
					homeworkVo.setStatus(Constant.HomeworkStatus.RUN);
					homeworkTask.getTodayList().add(homeworkVo);
					homeworkVo.setThisExecTime(new Date());
				}

				EntityTool.buildUpdBase(homeworkVo, StpUtil.getLoginIdAsString());
				homeworkService.updateById(homeworkVo);
				continue;
			}
		}

		return homeworkTask;
	}
}
